#!/usr/bin/env python2
#-*- coding: utf-8 -*-

import os
import re
import web
import json
import traceback

from sqlalchemy.orm.exc import NoResultFound
from Umpweb.base import render_jinja
from Umpweb.db import api as db_api
from Umpweb.common import utils
from Umpweb.common.utils import login_required


urls = (
        '/list',                            'DiskList',
        '/grid',                            'GridDisk',
        '/disk_overview',                   'DiskOverview',
        '/disk_add_confirm',                'DiskAddConfirm',
        '/disk_add',                        'DiskAdd',
        '/disk_add_force_confirm',          'DiskAddForceConfirm',
        '/disk_delete_confirm',             'DiskDeleteConfirm',
        '/disk_delete',                     'DiskDelete',
        '/disk_light_option',               'DiskLight',
        '/raid_add',                        'RaidAdd',
        '/raid_add_confirm',                'RaidAddConfirm',
        '/raid_add_force_confirm',          'RaidAddForceConfirm',
        '/raid_delete_confirm',             'RaidDeleteConfirm',
        '/raid_force_delete_confirm',       'RaidForceDeleteConfirm',
        '/raid_delete',                     'RaidDelete',
        '/raid_missing_confirm',            'RaidErrorConfirm',
        '/raid_missing',                    'RaidMissing',

)


app = web.application(urls, locals())
render = render_jinja('static/templates/disk', encoding='utf-8',)


class DiskOverview:
    @login_required
    def GET(self):
        web.header("Content-Type", "text/plain")
        hosts = db_api.host_get_all()
        hosts = sorted(hosts, key=lambda x :x.id)
        hosts.reverse()
        return render.disk_overview(hosts=hosts)

class DiskList:
    @login_required
    def GET(self):
        web.header("Content-Type", "text/plain")
        x = web.input()
        hosts = db_api.host_get_all()
        raid_missing_hostids = []
        raid_missing_hostips = []
        for host in hosts:
            host.disks = db_api.disk_get_with_host(host.id) 
            for disk in host.disks:
                if not disk.raid_missing:
                    continue
                raid_missing_hostids.append(str(host.id))
                raid_missing_hostips.append(host.ip)
                break
        raid_missing_hostids = ','.join(raid_missing_hostids)
        raid_missing_hostips = ','.join(set(raid_missing_hostips))
        return render.disk_list(hosts=hosts,\
                        raid_missing_hostips=raid_missing_hostips,\
                        raid_missing_hostids=raid_missing_hostids)


DISK_STAT_MAP = {
    'OK': '正常',
    'deleting': '删除中',
    'joining': '加入中',
    'Failed': '不正常',
    'Unconfigured(good)': '正常',
}

CACHE_STAT = {
    'None': 'N/A',
    '': 'N/A',
    'Enabled': '开启',
    'Disabled': '关闭',
}


class GridDisk:
    @login_required
    def GET(self):
        web_input = web.input()

        filters = {}
        host_id = web_input.get('host_id')
        if host_id:
            filters = {'host_id':host_id}

        page, total, records, rows = utils.grid_rows_query(db_api.disk_table, web_input, filters )
        
        
        for disk in rows:
            disk.stat_ch = DISK_STAT_MAP.get(disk.stat, disk.stat)
            disk.raid_cache_ch = CACHE_STAT.get(disk.raid_cache, disk.raid_cache)
            disk.disk_cache_ch = CACHE_STAT.get(disk.disk_cache, disk.disk_cache)

            disk.size_show = disk.page_show_size
            if disk.stat =='Failed':
                disk.size_show = "%.0fG"%0
            disk.page_show_usage_ = disk.page_show_usage
            if disk.pre_stat =='Failed' and disk.stat == 'deleting':
                disk.size_show = "%.0fG"%0
                disk.page_show_usage_ = "0"
                #disk.page_show_usage_ = "0.00"

            disk.type = disk.media_type
            if disk.media_type == 'unknown':
                disk.type = u'N/A'

            if not disk.isjoin:
                disk.status_ch = u'停止'
                if disk.status == 'running':
                    disk.status_ch = u'运行'
                if disk.status == 'stopping':
                    disk.status_ch = u'停止中'
            else:
                disk.status_ch = u'无服务'
                if disk.pre_stat == 'OK' and  disk.stat_ch =='删除中':
                    disk.stat_ch = '正常'
                if disk.pre_stat == 'Failed' and  disk.stat_ch =='删除中':
                    disk.stat_ch= '不正常'
            disk.islight = disk.light_stat

            disk.mount_point_show = '' 
            if disk.isjoin:
                disk.status = 'unknown'
                if disk.stat == 'deleting':
                    disk.stat = 'OK'
            disk.isjoin_show = '否'
            if not disk.isjoin :
                disk.isjoin_show = '是'
            disk.mountpoint_show = disk.mountpoint
            disk.device_show = disk.device.split('/')[2] if '/' in disk.device else disk.device

        cells = ['id', 'host_ip', 'device_show', 'page_show_usage_', 'used', 'size_show', 'mountpoint_show', 
                'isjoin_show', 'isjoin', 'host_id', 'islight', 'stat_ch', 'enable_delete', 'disk_option',
                'tier', 'type', 'disk_light', 'interface', 'raid_cache_ch', 'disk_cache_ch',
                'serial_number', 'raid', 'adp_name', 'raid_missing', 'used']

        rows_json = utils.grid_json(page,total,records,rows,'id',cells)
        web.header("Conten-Type","application/json")
        return rows_json

    def get_tb(self,val):
        if val > 1000000000:
            #val = "%.1f T"%float(int(val)/1000/1000/1000)
            val = "%.0f T" % float(int(val) / 1000 / 1000 / 1000)
        else:
            #val = "%.f G"%float((int(val)/1000/1000))
            val = "%.0f G" % float((int(val) / 1000 / 1000))
        return val

class DiskAddConfirm:
    def GET(self):
        x = web.input()
        web.header("Content-Type", "text/plain")
        disk_id = x.get('disk_id')
        disk = db_api.disk_get(disk_id)
        return render.disk_add_confirm(disk=disk)

class DiskAdd:
    def POST(self):
        web.header("Content-Type", "application/json")
        x = web.input()
        values = dict(**web.input())
        body = {'DiskAdd':{'params':values}}
        return utils.web_return(body)


class DiskAddForceConfirm:
    def GET(self):
        x = web.input()
        web.header("Content-Type", "text/plain")
        disk_id = x.get('disk_id')
        disk = db_api.disk_get(disk_id)
        return render.disk_add_force_confirm(disk=disk)


class DiskDeleteConfirm:
    def GET(self):
        x = web.input()
        web.header("Content-Type", "text/plain")
        disk_id = x.get('disk_id')
        disk = db_api.disk_get(disk_id)
        return render.disk_delete_confirm(disk=disk)

class DiskDelete:
    def GET(self):
        x = web.input()
        web.header("Content-Type", "application/json")
        force = x.get('force'),
        is_force = False
        if force == 'true':
            is_force = True
        values = {
            'host_id': x.get('host_id'),
            'disk_id': x.get('disk_id'),
            'is_force': is_force,
        }
        body = {'DiskDelete':{'params':values}}
        return utils.web_return(body)


class RaidAdd:
    def POST(self):
        x = web.input() 
        web.header("Content-Type", "application/json")
        force = x.get('force')
        disk_id = x.get('disk_id')
        values = {
            'disk_id': x.get('disk_id'),
            'is_force': force,
        }
        body = {'RaidAdd':{'params':values}}
        return utils.web_return(body)


class RaidAddForceConfirm:
    def GET(self):
        x = web.input()
        web.header("Content-Type", "text/plain")
        disk_id = x.get('disk_id')
        disk = db_api.disk_get(disk_id)
        return render.raid_add_force_confirm(disk=disk)



class RaidForceDeleteConfirm:
    def GET(self):
        x = web.input()
        web.header("Content-Type", "text/plain")
        disk_id = x.get('disk_id')
        disk = db_api.disk_get(disk_id)
        return render.raid_force_delete_confirm(disk=disk)


class RaidDeleteConfirm:
    def GET(self):
        x = web.input()
        web.header("Content-Type", "text/plain")
        disk_id = x.get('disk_id')
        disk = db_api.disk_get(disk_id)
        return render.raid_delete_confirm(disk=disk)


class RaidDelete:
    def GET(self):
        x = web.input()
        web.header("Content-Type", "application/json")
        force = x.get('force')
        disk_id = x.get('disk_id')
        is_force = False
        if force == 'true':
            is_force = True
        values = {
            'disk_id': x.get('disk_id'),
            'is_force': is_force,
        }
        body = {'RaidDelete':{'params':values}}
        return utils.web_return(body)

class DiskLight:
    def GET(self):
        x = web.input()
        web.header("Content-Type", "application/json")
        disk_id = x.get('disk_id')
        option = x.get('option')
        values = {
            'disk_id': disk_id,
            'option': option,
        }
        body = {'DiskLight':{'params':values}}
        return utils.web_return(body)

class RaidErrorConfirm:
    def GET(self):
        x = web.input()
        web.header("Content-Type", "text/plain")
        return render.raid_missing_confirm(**(dict(x)))

class RaidMissing:
    def GET(self):
        x = web.input()
        hostids = x.get('hostids', '').split(',')
        web.header("Content-Type", "application/json")
        body = {'RaidMissing':{'params':{'hostids':hostids}}}
        return utils.web_return(body)

class RaidAddConfirm:
    def GET(self):
        x = web.input()
        web.header("Content-Type", "text/plain")
        disk_id = x.get('disk_id')
        disk = db_api.disk_get(disk_id)
        return render.raid_add_confirm(disk=disk)

